[ Prev Page | Goto Content | Next Page ]
=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\
;; socket coding on asm/x86 ;; Как юзать сокеты на асме? В регистр %eax суём $102 (номер вызова socketcall). Далее, в %ebx идёт номер функции для работы с сокетом. А в %ecx кладём адрес, по которому лежат аргументы. Номера функций для socketcall'a (): #define SYS_SOCKET 1 /* sys_socket(2) */ #define SYS_BIND 2 /* sys_bind(2) */ #define SYS_CONNECT 3 /* sys_connect(2) */ #define SYS_LISTEN 4 /* sys_listen(2) */ #define SYS_ACCEPT 5 /* sys_accept(2) */ #define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ #define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ #define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ #define SYS_SEND 9 /* sys_send(2) */ #define SYS_RECV 10 /* sys_recv(2) */ #define SYS_SENDTO 11 /* sys_sendto(2) */ #define SYS_RECVFROM 12 /* sys_recvfrom(2) */ #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ Каждый аргумент имеет длину 4 байта (тип long), и соответственно самый перый должен лежать на самом верху. Пример: pushl $0 # INADDR_ANY pushw $0x3500 # port pushw $2 # AF_INET movl %esp,%edx И вот что мы получаем в памяти: 0x02 0x00 # word family = AF_INET 0x00 0x35 # word port = 53 0x00 0x00 0x00 0x00 # long s_addr = INADDR_ANY Кстати, структуру sockaddr лучше создавать впрямо в стеке-по крайней мере, это позволит избавиться от лишних ошибок. Длина структуры всегда 16 байт ! Тоесть мы имеем первые 2 байта для хранения семейства сокета (в нашем случае AF_INET=2), а всё остальное заполянем нулями и используем столько, сколько нужно данному типу сокетов. Тоесть нам нужно только 6 байт. Вот все типы сокетов в 2.4.x : #define AF_UNSPEC 0 #define AF_UNIX 1 /* Unix domain sockets */ #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ #define AF_INET 2 /* Internet IP Protocol */ #define AF_AX25 3 /* Amateur Radio AX.25 */ #define AF_IPX 4 /* Novell IPX */ #define AF_APPLETALK 5 /* AppleTalk DDP */ #define AF_NETROM 6 /* Amateur Radio NET/ROM */ #define AF_BRIDGE 7 /* Multiprotocol bridge */ #define AF_ATMPVC 8 /* ATM PVCs */ #define AF_X25 9 /* Reserved for X.25 project */ #define AF_INET6 10 /* IP version 6 */ #define AF_ROSE 11 /* Amateur Radio X.25 PLP */ #define AF_DECnet 12 /* Reserved for DECnet project */ #define AF_NETBEUI 13 /* Reserved for 802.2LLC project */ #define AF_SECURITY 14 /* Security callback pseudo AF */ #define AF_KEY 15 /* PF_KEY key management API */ #define AF_NETLINK 16 #define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */ #define AF_PACKET 17 /* Packet family */ #define AF_ASH 18 /* Ash */ #define AF_ECONET 19 /* Acorn Econet */ #define AF_ATMSVC 20 /* ATM SVCs */ #define AF_SNA 22 /* Linux SNA Project (nutters!) */ #define AF_IRDA 23 /* IRDA sockets */ #define AF_PPPOX 24 /* PPPoX sockets */ #define AF_MAX 32 /* For now.. */ Всякие PF_INET,PF_UNIX,etc просто ссылаются на эти значения,так что это всегда одно и то же. Для создания сокета (для вызова sys_socket()) нам нужно знать помимо семейства сокета его тип и протокол. Типы сокетов : #define SOCK_STREAM 1 /* stream (connection) socket */ #define SOCK_DGRAM 2 /* datagram (conn.less) socket */ #define SOCK_RAW 3 /* raw socket */ #define SOCK_RDM 4 /* reliably-delivered message */ #define SOCK_SEQPACKET 5 /* sequential packet socket */ #define SOCK_PACKET 10 /* linux specific way of */ А тут перечислены все основные протоколы (): IPPROTO_IP = 0, /* Dummy protocol for TCP. */ IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */ IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */ IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94). */ IPPROTO_TCP = 6, /* Transmission Control Protocol. */ IPPROTO_EGP = 8, /* Exterior Gateway Protocol. */ IPPROTO_PUP = 12, /* PUP protocol. */ IPPROTO_UDP = 17, /* User Datagram Protocol. */ IPPROTO_IDP = 22, /* XNS IDP protocol. */ IPPROTO_TP = 29, /* SO Transport Protocol Class 4. */ IPPROTO_IPV6 = 41, /* IPv6 header. */ IPPROTO_ROUTING = 43, /* IPv6 routing header. */ IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ IPPROTO_RSVP = 46, /* Reservation Protocol. */ IPPROTO_GRE = 47, /* General Routing Encapsulation. */ IPPROTO_ESP = 50, /* encapsulating security payload. */ IPPROTO_AH = 51, /* authentication header. */ IPPROTO_ICMPV6 = 58, /* ICMPv6. */ IPPROTO_NONE = 59, /* IPv6 no next header. */ IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ IPPROTO_MTP = 92, /* Multicast Transport Protocol. */ IPPROTO_ENCAP = 98, /* Encapsulation Header. */ IPPROTO_PIM = 103, /* Protocol Independent Multicast. */ IPPROTO_COMP = 108, /* Compression Header Protocol. */ IPPROTO_RAW = 255, /* Raw IP packets. */ IPPROTO_MAX А вот и пример проги, работающей с raw-сокетами: .globl _start _start: subl $0x20,%esp # обнуляем 32 байта в стеке # sock =socket(AF_INET,SOCK_RAW,IPPROTO_UDP) xorl %eax,%eax movl $2,(%esp) # AF_INET movl $3,0x4(%esp) # SOCK_RAW movl $17,0x8(%esp) # UDP proto movl %esp,%ecx # кладём адрес аргументов в %ecx movl $1,%ebx # sys_socket() mov $102,%al # sys_socketcall() int $128 movl %eax,%edx # сохраняем сокет в %edx, т.к. он не используется # setsockopt(sock,SOL_IP,IP_HDRINCL,(char *) &optval, 4) movl %edx,(%esp) # указатель на наш сокет movl $0,0x4(%esp) # SOL_IP movl $3,0x8(%esp) # IP_HDRINCL = 3 (g0t0 ) movl $optval,0xc(%esp) # value movl $4,0x10(%esp) # 4 байта, т.к. optval это адрес movl $14,%ebx # sys_setsockopt() movl $102,%eax # sys_socketcall() int $128 # sendto(sock,rawpacket,sizeof(rawpacket),0,(struct sockaddr *) &suck,16) movl %edx,(%esp) # указатель movl $rawpacket,0x4(%esp) # адрес, по которому лежит пакет movl $30,0x8(%esp) # размер пакета movl $0,0xc(%esp) # flags 0 # начинаем заполнять структуру sockaddr: movw $2,0x18(%esp) # family = AF_INET movw $0x3500,0x1a(%esp) # port 53 movl $0x0100007f,0x1c(%esp) # dst ip: 127.0.0.1 # всё остальное пространство в после daddr мы заполнили нулями в самом начале, # так что мы используем наши 8 байт, а остальное просто не трогаем. lea 0x18(%esp),%ebx # вычисляем адерс нашей структуры sockaddr... movl %ebx,0x10(%esp) # ...и кладём в стек 5-м аргументом movl $16,0x14(%esp) # 6-й аргумент - размер структуры sockaddr movl $11,%ebx # sys_sendto() movl $102,%eax # sys_socketcall() int $128 movl %edx,%ebx # указатель на сокет - первый аргумент movl $6,%eax # close() syscall int $128 movl $1,%eax # exit() syscall int $128 optval: .byte 0x13 # justa value rawpacket: .ascii "\x45" # ver=4; ihl=5 .ascii "\x9f" # tos bits = 10011110 (wrrr000mm!!) .ascii "\x00\x30" # tot_len .ascii "\x32\x8f" # id .ascii "\x40\x00" # flags .ascii "\xff" # ttl .ascii "\x11" # udp proto .ascii "\x00\x00" # ip header checksum - заполняется ядром .ascii "\x0d\x06\x06\x06" # src ip: 13.6.6.6 .ascii "\x7f\x00\x00\x01" # dst ip: 127.0.0.1 # udp header: .ascii "\x00\x35" # src port 53 .ascii "\x00\x35" # dst port 53 .ascii "\x00\x0a" # udp + payload len .ascii "\xa0\x63" # udp + payload checksum # ma small payload: .ascii "\x61\x0a" # aka "a\n" Вот собственно и всё, что хотелось сказать. И на последок пара трюков: [hint 1]: для SOL_TCP (sock object level для протокола TCP) есть одна интересная опция TCP_NODELAY. Она отключает буферизацию инфы, и следовательно обработчик tcp-пакетов будет сразу слать полученные данные проге. Так можно немного ускорить/улучшить соединение. [hint 2]: используя TOS можно добиться того, что роутеры, поддерживающие данные режимы будут скажем быстрее обрабатывать наши пакеты. Вот формат tos: bits: 0--1--2--3--4--5--6--7 A A A B C D E 0 AAA (первые три бита) - приоритет датаграммы. Значения: 111 - управление сетью ( heh, hypa-speed? ;) 110 - межсетевое управление 101 - CRITIC-ECP 100 - более чем мгновенно (what da nice shit) 011 - мгновенно 010 - немедленно 001 - срочно 000 - обчно B (1 бит) - выбор маршрута с минимальной задержкой С (1 бит) - выбор маршрута с максимальной пропускной способносью D (1 бит) - выбор маршрута с максимальной надёжностью E (1 бит) - выбор маршрута с минимальной стоимостью Удачных эксперементов! [ Prev Page | Goto Content | Next Page ]